﻿// ******************************************************************
// * Copyright(c)  Steven Lu
// * Description   : Entity_INV_MTRL_TRANS
// * CreateDate    : 2014/3/11 11:20:30
// * Creater       : CodeSmith
// * LastChangeDate: 2014/3/11 11:20:30
// * LastChanger   : 2014/3/11 11:20:30
// * Version Info  : 1.0 For ESOL
// ******************************************************************

using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Suzsoft.Smart.Data;
using ESOL.Common.Entity;
using ESOL.Business.Mst;
using ESOL.Common;

namespace ESOL.Business.Inv
{
    /// <summary>
    /// InvMtrlTrans
    /// </summary>
    public partial class InvMtrlTransBs
    {
        #region GetByID
        /// <summary>
        /// Get Entity
        /// </summary>
        /// <param name="objInvMtrlTransEntity">Entity</param>
        /// <returns>Entity</returns>
        public static InvMtrlTransEntity GetInvMtrlTrans(InvMtrlTransEntity objInvMtrlTransEntity)
        {
            return DataAccess.SelectSingle<InvMtrlTransEntity>(objInvMtrlTransEntity);
        }
        #endregion


        #region Insert
        /// <summary>
        /// Insert Data
        /// </summary>
        /// <param name="objInvMtrlTransEntity">Entity</param>
        /// <returns>true Insert Succeed; false Insert Fail</returns>
        public static bool InsertInvMtrlTrans(InvMtrlTransEntity objInvMtrlTransEntity)
        {
            return DataAccess.Insert(objInvMtrlTransEntity);
        }

        public static bool InsertInvMtrlTrans(List<InvMtrlTransEntity> objInvMtrlTransEntityList)
        {
            return DataAccess.Insert(objInvMtrlTransEntityList);
        }
        #endregion


        #region Update
        /// <summary>
        /// Update Data
        /// </summary>
        /// <param name="objInvMtrlTransEntity">Entity</param>
        /// <returns>true Update Succeed; false Update Fail</returns>
        public static bool UpdateInvMtrlTrans(InvMtrlTransEntity objInvMtrlTransEntity)
        {
            return DataAccess.Update(objInvMtrlTransEntity);
        }

        public static bool UpdateInvMtrlTrans(List<InvMtrlTransEntity> objInvMtrlTransEntityList)
        {
            return DataAccess.Update<InvMtrlTransEntity>(objInvMtrlTransEntityList);
        }
        #endregion


        #region Delete
        /// <summary>
        /// Delete Data
        /// </summary>
        /// <param name="objInvMtrlTransEntity">Entity</param>
        /// <returns>true Delete Succeed; false Delete Fail</returns>
        public static bool DeleteInvMtrlTrans(InvMtrlTransEntity objInvMtrlTransEntity)
        {
            return DataAccess.Delete(objInvMtrlTransEntity);
        }

        public static bool DeleteInvMtrlTrans(List<InvMtrlTransEntity> objInvMtrlTransEntityList)
        {
            return DataAccess.Delete<InvMtrlTransEntity>(objInvMtrlTransEntityList);
        }
        #endregion


        #region GetAll
        /// <summary>
        /// Get All Data
        /// </summary>
        /// <returns>Back All Data<returns>
        public static DataSet GetInvMtrlTransAll()
        {
            return DataAccess.SelectAllDataSet<InvMtrlTransEntity>();
        }
        /// <summary>
        /// Get All Data List
        /// </summary>
        /// <returns>Back All Data List<returns>
        public static List<InvMtrlTransEntity> GetInvMtrlTransAllList()
        {
            return DataAccess.SelectAll<InvMtrlTransEntity>();
        }
        #endregion


        public static InvMtrlTransEntity AddInvMtrlTransAndItem(InvMtrlTransEntity mtrlRequisition, List<InvMtrlTransItemEntity> Mtrls)
        {
            using (DataAccessBroker broker = DataAccessFactory.Instance())
            {
                try
                {
                    InvOappEntity oapp = null;
                    var oappi_list = new List<InvOappiEntity>();
                    InvIappEntity iapp = null;
                    List<InvIappiEntity> iappItems = new List<InvIappiEntity>();
                    if (string.IsNullOrEmpty(mtrlRequisition.TransNo))
                    {
                       
                        if (mtrlRequisition.TransType.Equals(Common.WoTransType.Mtrl_Req.ToString()))
                        {
                             #region 工单领料
                            mtrlRequisition.TransNo = ESOL.Business.Mst.MstCodeRuleBs.GetCurrentOrderCode("MtrlRequisition");
                            oapp = CreateOApp(mtrlRequisition);

                            foreach (InvMtrlTransItemEntity mtrl in Mtrls)
                            {
                                mtrl.TransNo = mtrlRequisition.TransNo;
                                //添加仓库视图的用料申请
                                InvOappiEntity oappItem = CreateOAppItem(oapp.Id, mtrl);
                                oappi_list.Add(oappItem);
                            }
                         #endregion

                        }
                        else if (mtrlRequisition.TransType.Equals(Common.WoTransType.Mtrl_Ret.ToString()))
                        {
                            #region 工单退料
                        
                            mtrlRequisition.TransNo = ESOL.Business.Mst.MstCodeRuleBs.GetCurrentOrderCode("MtrlReturn");
                            iapp = CreateIApp(mtrlRequisition);

                            foreach (InvMtrlTransItemEntity mtrl in Mtrls)
                            {
                                mtrl.TransNo = mtrlRequisition.TransNo;
                                //添加仓库视图的用料申请
                                InvIappiEntity iappItem = CreateIAppItem(iapp.Id, mtrl);
                                iappItems.Add(iappItem);
                            }
                            #endregion
                        }
                        else if (mtrlRequisition.TransType.Equals(Common.WoTransType.Mtrl_Supt.ToString()))
                        {
                            #region 工单超领/计划外领料
                            mtrlRequisition.TransNo = ESOL.Business.Mst.MstCodeRuleBs.GetCurrentOrderCode("MtrlSupt");
                            oapp = CreateOApp(mtrlRequisition);

                            foreach (InvMtrlTransItemEntity mtrl in Mtrls)
                            {
                                mtrl.TransNo = mtrlRequisition.TransNo;
                                //添加仓库视图的用料申请
                                InvOappiEntity oappItem = CreateOAppItem(oapp.Id, mtrl);
                                oappi_list.Add(oappItem);
                            }
                            #endregion
                        }

                       
                    }
                    broker.BeginTransaction();
                   // DataAccess.Update(updateWoMtrlEntities, broker);
                    DataAccess.Insert(mtrlRequisition,broker);
                    DataAccess.Insert<InvMtrlTransItemEntity>(Mtrls,broker);

                    if(oapp!=null) DataAccess.Insert(oapp,broker);
                    if (oappi_list != null) DataAccess.Insert(oappi_list, broker);

                    if (iapp != null)
                    {
                        DataAccess.Insert(iapp, broker);
                        if (iappItems.Count > 0) DataAccess.Insert(iappItems, broker);
                    }

                    broker.Commit();
                    return mtrlRequisition;
                }
                catch (Exception ex)
                {
                    broker.RollBack();
                    throw ex;
                }
            }
        }

        private static InvOappEntity CreateOApp(InvMtrlTransEntity mtrlReq)
        {
            InvOappEntity oapp = new InvOappEntity();
            oapp.Id = Guid.NewGuid().ToString();
            oapp.CreatedBy = mtrlReq.CreatedBy;
            oapp.CreatedDate = DateTime.Now;
            oapp.UpdatedBy = mtrlReq.UpdatedBy;
            oapp.UpdatedDate = DateTime.Now;
            oapp.IsActive = mtrlReq.IsActive;
            oapp.AppNo = MstCodeRuleBs.GetCurrentOrderCode("InvOutAppOrder");
            if(mtrlReq.TransType.Equals(Common.WoTransType.Mtrl_Req.ToString()))
                oapp.Type = (int)InvOutType.工单领料出库;
            else if (mtrlReq.TransType.Equals(Common.WoTransType.Mtrl_Supt.ToString()))
                oapp.Type = (int)InvOutType.工单超领;
            oapp.RelatedId = mtrlReq.TransNo;
            oapp.Remark = mtrlReq.Remark;
            oapp.Status = Common.WfStatus.WFS10.ToString();
            return oapp;
        }

        private static InvOappiEntity CreateOAppItem(string reqNo,InvMtrlTransItemEntity mtrl)
        {
            var oappi = new InvOappiEntity();
            oappi.Id = Guid.NewGuid().ToString();
            oappi.OoAppId = reqNo;
            oappi.ProductId = mtrl.MaterialId;
            oappi.Qty = mtrl.ReqQty;
            //oappi.Unit = mtrl.Unit;
            return oappi;
        }

        private static InvIappEntity CreateIApp(InvMtrlTransEntity mtrlReq)
        {
            InvIappEntity iapp = new InvIappEntity();
            iapp.Id = Guid.NewGuid().ToString();
            iapp.CreatedBy = mtrlReq.CreatedBy;
            iapp.CreatedDate = DateTime.Now;
            iapp.UpdatedBy = mtrlReq.UpdatedBy;
            iapp.UpdatedDate = DateTime.Now;
            iapp.IsActive = mtrlReq.IsActive;
            iapp.AppNo = MstCodeRuleBs.GetCurrentOrderCode("InvInAppOrder");
            iapp.Type = (int)InvInType.工单退料;
            iapp.RelatedId = mtrlReq.TransNo;
            iapp.Remark = mtrlReq.Remark;
            iapp.Status = Common.WfStatus.WFS10.ToString();
            return iapp;
        }

        private static InvIappiEntity CreateIAppItem(string reqNo, InvMtrlTransItemEntity mtrl)
        {
            var oappi = new InvIappiEntity();
            oappi.Id = Guid.NewGuid().ToString();
            oappi.IoAppId = reqNo;
            oappi.ProductId = mtrl.MaterialId;
            oappi.Qty = mtrl.ReqQty;
           // oappi = mtrl.Unit;
            return oappi;
        }


        public static InvMtrlTransEntity UpdateInvMtrlTransAndItem(InvMtrlTransEntity mtrlRequisition, List<InvMtrlTransItemEntity> Mtrls)
        {
            using (DataAccessBroker broker = DataAccessFactory.Instance())
            {
                try
                {
                    
                    List<InvOappiEntity> addOappItem = new List<InvOappiEntity>();
                    InvOappEntity updateOapp = new InvOappEntity();
                    List<InvIappiEntity> addIappItem = new List<InvIappiEntity>();
                    InvIappEntity updateIapp = new InvIappEntity();
                  
                    List<InvMtrlTransItemEntity> deleteMtrls = DataAccess.Select<InvMtrlTransItemEntity>(new InvMtrlTransItemEntity { TransNo = mtrlRequisition.TransNo });

                    if (mtrlRequisition.TransType.Equals(Common.WoTransType.Mtrl_Req.ToString()))
                    {
                        #region 工单领料
                        updateOapp = DataAccess.SelectSingle<InvOappEntity>(new InvOappEntity { RelatedId = mtrlRequisition.TransNo });
                        foreach (InvMtrlTransItemEntity mtrl in Mtrls)
                        {
                            if (updateOapp != null)
                            {
                                InvOappiEntity oappItem = CreateOAppItem(updateOapp.Id, mtrl);
                                addOappItem.Add(oappItem);
                            }
                        }
                        #endregion 
                    }
                    else if (mtrlRequisition.TransType.Equals(Common.WoTransType.Mtrl_Ret.ToString()))
                    {
                        #region 工单退料
                        updateIapp = DataAccess.SelectSingle<InvIappEntity>(new InvIappEntity { RelatedId = mtrlRequisition.TransNo });
                        foreach (InvMtrlTransItemEntity mtrl in Mtrls)
                        {
                            if (updateIapp != null)
                            {
                                InvIappiEntity iappItem = CreateIAppItem(updateIapp.Id, mtrl);
                                addIappItem.Add(iappItem);
                            }
                        }
                        #endregion
                    }
                    broker.BeginTransaction();
                    //同步仓库视图的物料申请单
                    List<InvOappiEntity> deleteOAppItems = null;
                    if (updateOapp != null)
                    {
                        deleteOAppItems = DataAccess.Select<InvOappiEntity>(new InvOappiEntity { OoAppId = updateOapp.Id });
                        if (deleteOAppItems != null && deleteOAppItems.Count > 0)
                            DataAccess.Delete(deleteOAppItems, broker);
                        if (addOappItem != null && addOappItem.Count > 0)
                            DataAccess.Insert(addOappItem, broker);
                    }

                    List<InvIappiEntity> deleteIAppItems = null;
                    if (updateIapp != null)
                    {
                        deleteIAppItems = DataAccess.Select<InvIappiEntity>(new InvIappiEntity { IoAppId = updateIapp.Id });
                        if (deleteIAppItems != null && deleteIAppItems.Count > 0)
                            DataAccess.Delete(deleteIAppItems, broker);
                        if (addIappItem != null && addIappItem.Count > 0)
                            DataAccess.Insert(addIappItem, broker);
                    }


                    //更新物料申请单索引表
                    mtrlRequisition.UpdatedDate = DateTime.Now;
                    DataAccess.Update(mtrlRequisition,broker);

                    //更新物料申请单明细表
                    if (deleteMtrls != null) DataAccess.Delete<InvMtrlTransItemEntity>(deleteMtrls,broker);
                    DataAccess.Insert(Mtrls,broker);

                    broker.Commit();
                    return mtrlRequisition;
                }
                catch (Exception ex)
                {
                    broker.RollBack();
                    throw ex;
                }
            }
        }


        public static bool DeleteInvMtrlTransAndItem(InvMtrlTransEntity mtrlRequisition)
        {
            using (DataAccessBroker broker = DataAccessFactory.Instance())
            {
                try
                {
                    InvOappEntity updateOapp = null;
                    InvIappEntity updateIapp = null;
                    List<InvIappiEntity> deleteIAppItems = null;
                    List<InvOappiEntity> deleteOAppItems = null;
                    if (mtrlRequisition.TransType.Equals(Common.WoTransType.Mtrl_Req.ToString()))
                    {
                        #region 工单领料
                         updateOapp = DataAccess.SelectSingle<InvOappEntity>(new InvOappEntity { RelatedId = mtrlRequisition.TransNo });
                         deleteOAppItems = DataAccess.Select<InvOappiEntity>(new InvOappiEntity { OoAppId = updateOapp.Id });
                        
                        #endregion
                    }
                    else if (mtrlRequisition.TransType.Equals(Common.WoTransType.Mtrl_Ret.ToString()))
                    {
                        #region 工单退料
                         updateIapp = DataAccess.SelectSingle<InvIappEntity>(new InvIappEntity { RelatedId = mtrlRequisition.TransNo });
                         deleteIAppItems = DataAccess.Select<InvIappiEntity>(new InvIappiEntity { IoAppId = updateIapp.Id });
                        #endregion
                    }


                    broker.BeginTransaction();
                    List<InvMtrlTransItemEntity> deleteMtrls = DataAccess.Select<InvMtrlTransItemEntity>(new InvMtrlTransItemEntity { TransNo = mtrlRequisition.TransNo });
                    if (deleteMtrls != null) DataAccess.Delete<InvMtrlTransItemEntity>(deleteMtrls,broker);
                    DataAccess.Delete(mtrlRequisition,broker);
                    if (updateIapp != null)
                    {
                        DataAccess.Delete(updateIapp, broker);
                        if (deleteIAppItems.Count > 0) DataAccess.Delete(deleteIAppItems, broker);
                    }
                    if (updateOapp != null)
                    {
                        DataAccess.Delete(updateOapp, broker);
                        if (deleteOAppItems.Count > 0) DataAccess.Delete(deleteOAppItems, broker);
                    }
                    broker.Commit();
                    return true;
                }
                catch (Exception ex)
                {
                    broker.RollBack();
                    throw ex;
                }
            }
        }



        public static List<InvMtrlTransEntity> GetInvMtrlTransByCondition(InvMtrlTransQueryCondition condition)
        {

            InvMtrlTransEntity entiyCodition = TransferCondition(condition);
            return DataAccess.Select<InvMtrlTransEntity>(entiyCodition);
        }

        public static InvMtrlTransEntity TransferCondition(InvMtrlTransQueryCondition condition)
        {
            InvMtrlTransEntity entiy = new InvMtrlTransEntity();
            if (!string.IsNullOrEmpty(condition.WoNo))
                entiy.WoNo = condition.WoNo;
            if (!string.IsNullOrEmpty(condition.Status))
                entiy.Status = condition.Status;
            if (!string.IsNullOrEmpty(condition.TransType))
                entiy.TransType = condition.TransType;
            if (!string.IsNullOrEmpty(condition.CreatedBy))
                entiy.CreatedBy = condition.CreatedBy;
            return entiy;

        }



        //计算工单用料可以领取的最大数量
        public static decimal GetAllowReqMaxQty(string woNo, string transNo, string mtrlId)
        {

            ProdWoMtrlEntity woMtrl = DataAccess.SelectSingle<ProdWoMtrlEntity>(new ProdWoMtrlEntity { WoNo=woNo, MtrlId=mtrlId});
            if (woMtrl == null) return 0;
            decimal allowReqQty = woMtrl.ReqQty - woMtrl.UsedQty ;
            //已申请未发料的数量
            string sql = @" select isnull(SUM( item.REQ_QTY-isnull(item.TRANS_QTY,0)),0) TotalReqedQty from INV_MTRL_TRANS trans left join INV_MTRL_TRANS_ITEM item on trans.TRANS_NO=item.TRANS_NO
                            where trans.WO_NO='{0}' and trans.STATUS in('{1}','{2}','{3}','{4}') and item.MATERIAL_ID='{5}' and trans.TRANS_TYPE='{6}' ";
            if (!string.IsNullOrEmpty(transNo))
                sql += " and trans.TRANS_NO !='" + transNo + "'";

            sql = string.Format(sql, woNo, Common.WoTransStatus.Active.ToString(), Common.WoTransStatus.Daft.ToString(), Common.WoTransStatus.Run.ToString(), Common.WoTransStatus.Sign.ToString(), mtrlId, Common.WoTransType.Mtrl_Req.ToString());
            DataSet ds = DataAccess.SelectDataSet(sql);
            decimal totalReqedQty=0;
            if (ds != null && ds.Tables.Count > 0)
            {
                totalReqedQty = Convert.ToDecimal(ds.Tables[0].Rows[0][0]);
            }

            return allowReqQty - totalReqedQty;
            
        }



        //计算工单用料可以退回的最大数量
        public static decimal GetAllowReturnMaxQty(string woNo, string transNo, string mtrlCode)
        {

            ProdWipMtrlCurEntity wipMtrl = DataAccess.SelectSingle<ProdWipMtrlCurEntity>(new ProdWipMtrlCurEntity { WoNo = woNo, MtrlCode = mtrlCode });
            if (wipMtrl == null) return 0;
            decimal allowReqQty = wipMtrl.MtrlQty;
            //已申请未发料的数量
            string sql = @" select isnull(SUM( item.REQ_QTY-isnull(item.TRANS_QTY,0)),0) TotalReqedQty from INV_MTRL_TRANS trans left join INV_MTRL_TRANS_ITEM item on trans.TRANS_NO=item.TRANS_NO
                            where trans.WO_NO='{0}' and trans.STATUS in('{1}','{2}','{3}','{4}') and item.MATERIAL_Code='{5}' and trans.TRANS_TYPE='{6}' ";
            if (!string.IsNullOrEmpty(transNo))
                sql += " and trans.TRANS_NO !='" + transNo + "'";

            sql = string.Format(sql, woNo, Common.WoTransStatus.Active.ToString(), Common.WoTransStatus.Run.ToString(), Common.WoTransStatus.Sign.ToString(),
                                Common.WoTransStatus.Daft.ToString(),mtrlCode,Common.WoTransType.Mtrl_Ret.ToString());
            DataSet ds = DataAccess.SelectDataSet(sql);
            decimal totalReqedQty = 0;
            if (ds != null && ds.Tables.Count > 0)
            {
                totalReqedQty = Convert.ToDecimal(ds.Tables[0].Rows[0][0]);
            }

            return allowReqQty - totalReqedQty;

        }
       
    }


}

